/*
 * Copyright (c) 2006-2021, Halo team
 *
 * SPDX-License-Identifier: GPLv3
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-09-11     Eywen        the first version
 */

#ifndef APPLICATIONS_EXTRUDER_H_
#define APPLICATIONS_EXTRUDER_H_

#include <rtthread.h>
#include <drivers/drv_smart_step.h>
#include "ringbuff.h"

typedef enum _extruder_step_type{
    extruder_step_single_material,   /* 单头单料 */
    extruder_step_duble_material,    /* 单头双料 */
    extruder_step_tril_material,     /* 单头三料 */
}extruder_step_type_t;

typedef struct _extruder_step_pulse
{
    float speed;                 /* 挤出速度, 正值为挤出，负值为回抽 */
    float capacity;              /* 挤出量, 正值为挤出，负值为回抽 */
}extruder_step_task_t;

typedef enum _extruder_step_status{
    extruder_step_running,                 /* 挤出机转动状态 */
    extruder_step_pause,                   /* 运行状态 */
}extruder_step_status_t;

typedef enum extruder_step_error{
    extruder_step_ok = 0,             /* 无错误 */
    extruder_step_err_uninit,         /* 未初始化 */
    extruder_step_err_stall,          /* 堵转 */
    extruder_step_err_break,          /* 断料错误 */
    extruder_step_err_temp,           /* 温度错误 */
    extruder_step_err_unkown,         /* 未知错误 */
}extruder_step_err_t;

typedef struct _extruder_step_ops extruder_step_ops_t;

typedef struct _extruder_step{
    extruder_step_type_t type;              /* 挤出机类型 */
    float axis_length;                      /* 坐标轴长度 */
    float home_offset;                      /* 零点偏移 */
    smart_step_t *step_drv;                 /* 底层驱动接口 */
    extruder_step_ops_t *ops;                 /* 操作接口 */
    extruder_step_err_t err_status;           /* 错误状态 */
    extruder_step_status_t running_status;    /* 步进电机运行状态 */
}extruder_step_t;

typedef struct _extruder_step_ops{
    bool (*init)(extruder_step_t *device, extruder_step_type_t type,
                     smart_step_id_t id ,int pin_pwm, int pin_en, int pin_dir,
                     uint32_t timer_freq);
    bool (*add_task)(extruder_step_t *step, extruder_step_task_t *pulse);
    extruder_step_err_t (*error)(extruder_step_t *device);
    bool (*start_task)(extruder_step_t *step);
    void (*axis_range_set)(extruder_step_t *step, float axis_length);
    void (*axis_zero_offset_set)(extruder_step_t *step, float offset);
    float (*coordinate)(extruder_step_t *step);
    void (*forward_level_set)(extruder_step_t *step, bool level);
    bool (*task_full)(extruder_step_t *step);
    bool (*task_empty)(extruder_step_t *step);
}extruder_step_ops_t;

bool extruder_step_register(extruder_step_t *device);

#endif /* APPLICATIONS_EXTRUDER_H_ */
